package com.foodorder.service.impl;

import com.foodorder.service.FileStorageService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.StandardCopyOption;
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.UUID;

/**
 * 本地文件存储服务实现类
 */
@Service
public class LocalFileStorageServiceImpl implements FileStorageService {

    private static final Logger log = LoggerFactory.getLogger(LocalFileStorageServiceImpl.class);

    @Value("${file.upload-dir:uploads}")
    private String uploadDir;
    
    @Value("${file.base-url:http://localhost:8080/uploads}")
    private String baseUrl;

    @Override
    public String uploadFile(MultipartFile file, String folder) throws IOException {
        // 检查文件是否为空
        if (file.isEmpty()) {
            throw new IOException("无法存储空文件");
        }
        
        // 创建日期子目录
        String datePath = LocalDate.now().format(DateTimeFormatter.ofPattern("yyyy/MM/dd"));
        String folderPath = StringUtils.hasText(folder) ? folder + "/" + datePath : datePath;
        
        // 获取文件名和扩展名
        String originalFilename = StringUtils.cleanPath(Objects.requireNonNull(file.getOriginalFilename()));
        String fileExtension = getFileExtension(originalFilename);
        
        // 生成唯一文件名
        String newFilename = UUID.randomUUID() + fileExtension;
        
        // 构建完整的存储路径
        Path storagePath = Paths.get(uploadDir, folderPath).toAbsolutePath().normalize();
        
        // 如果目录不存在，则创建
        if (!Files.exists(storagePath)) {
            Files.createDirectories(storagePath);
        }
        
        // 构建文件存储的完整路径
        Path targetPath = storagePath.resolve(newFilename);
        
        // 保存文件
        try {
            Files.copy(file.getInputStream(), targetPath, StandardCopyOption.REPLACE_EXISTING);
            
            // 返回可访问的URL
            return baseUrl + "/" + folderPath + "/" + newFilename;
        } catch (IOException ex) {
            log.error("文件存储失败: " + ex.getMessage());
            throw new IOException("文件存储失败: " + ex.getMessage());
        }
    }

    @Override
    public List<String> uploadFiles(List<MultipartFile> files, String folder) throws IOException {
        List<String> urls = new ArrayList<>();
        for (MultipartFile file : files) {
            urls.add(uploadFile(file, folder));
        }
        return urls;
    }

    @Override
    public boolean deleteFile(String fileUrl) {
        if (!StringUtils.hasText(fileUrl) || !fileUrl.startsWith(baseUrl)) {
            return false;
        }
        
        try {
            // 从URL中提取相对路径
            String relativePath = fileUrl.substring(baseUrl.length());
            Path filePath = Paths.get(uploadDir, relativePath).toAbsolutePath().normalize();
            
            // 检查文件是否存在
            if (!Files.exists(filePath)) {
                return false;
            }
            
            // 删除文件
            return Files.deleteIfExists(filePath);
        } catch (IOException ex) {
            log.error("文件删除失败: " + ex.getMessage());
            return false;
        }
    }

    @Override
    public String getFileUrl(String fileName, String folder) {
        if (!StringUtils.hasText(fileName)) {
            return null;
        }
        
        String folderPath = StringUtils.hasText(folder) ? folder : "";
        return baseUrl + "/" + folderPath + "/" + fileName;
    }
    
    /**
     * 获取文件扩展名
     *
     * @param filename 文件名
     * @return 扩展名（包含点号，如.jpg）
     */
    private String getFileExtension(String filename) {
        if (filename == null || filename.isEmpty() || !filename.contains(".")) {
            return "";
        }
        return filename.substring(filename.lastIndexOf("."));
    }
} 